using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections;

namespace ResourceBlender_Express {
    /// <summary>
    /// Represents a resource bundle which can be changed before writing to the database (allowing the user to cancel the edit form)
    /// </summary>
    public class ChangeableBundle : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// The action to take for a ChangeableBundle
        /// </summary>
        public enum ChangeMode {
            None,
            Add,
            Edit,
            Delete
        }

        private string id = string.Empty,
                       name = string.Empty;
        private ChangeMode changeMode = ChangeMode.None;

        /// <summary>
        /// Gets or sets the bundle ID.
        /// </summary>
        /// <value>The ID.</value>
        public string ID {
            get { return id; }
            set { 
                id = value;
                RaiseChangeEvent("ID");
            }
        }
        
        /// <summary>
        /// Gets or sets the name of the bundle.
        /// </summary>
        /// <value>The name.</value>
        public string Name {
            get { return name; }
            set { 
                name = value;
                RaiseChangeEvent("Name");
            }
        }
        
        /// <summary>
        /// Gets or sets the action to take for this bundle.
        /// </summary>
        /// <value>The mode.</value>
        public ChangeMode Mode {
            get { return changeMode; }
            set { 
                changeMode = value;
                RaiseChangeEvent("Mode");
            }
        }

        /// <summary>
        /// Initializes a new ChangeableBundle with a random ID.
        /// </summary>
        public ChangeableBundle() {
            this.ID = Utils.GenID(true);
        }
        /// <summary>
        /// Initializes a new ChangeableBundle with the specified name and ID.
        /// </summary>
        /// <param name="id">The ID.</param>
        /// <param name="name">The name.</param>
        public ChangeableBundle(string id, string name) {
            this.id = id;
            this.name = name;
        }

        /// <summary>
        /// Raises a PropertyChanged event if listeners are subscribed
        /// </summary>
        /// <param name="name">The name.</param>
        private void RaiseChangeEvent(string name) {
            if(PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

        /// <summary>
        /// Compares ChangeableBundles by name.
        /// </summary>
        public class BundleNameComparer : IComparer<DictionaryEntry> {
            CaseInsensitiveComparer comp = new CaseInsensitiveComparer();
            public int Compare(DictionaryEntry x, DictionaryEntry y) {
                if(x.Value is ChangeableBundle && y.Value is ChangeableBundle) {
                    return comp.Compare((x.Value as ChangeableBundle).Name, (y.Value as ChangeableBundle).Name);
                } else {
                    return comp.Compare(x.Key, y.Key);
                }
            }
        }

        /// <summary>
        /// Compares the equality of ChangeableBundle names.
        /// </summary>
        public class BundleNameEqualityComparer : IEqualityComparer<string> {
            public bool Equals(string x, string y) {
                return x.Equals(y, StringComparison.InvariantCultureIgnoreCase);
            }
            public int GetHashCode(string obj) {
                return obj.GetHashCode();
            }
        }
    }
}
